//
//  LFNetworkTool.m
//  AntFarms
//
//  Created by LF on 2017/2/24.
//  Copyright © 2017年 GG. All rights reserved.
//

#import "LFNetworkTool.h"

#define PHPSESSID @"PHPSESSID"
#define COOKIES @"COOKIES"

// 网络状态
static BOOL isNetworkUse;

/**
 AFN 继承
 */
@interface LFHTTPClient : AFHTTPSessionManager

+ (instancetype) shareInstance;
@end

@implementation LFHTTPClient

/**
 单例
 
 @return 对象
 */
+ (instancetype) shareInstance
{
    static LFHTTPClient *client = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        client = [LFHTTPClient manager];
        
        client.responseSerializer = [AFHTTPResponseSerializer serializer];
        client.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
//        [client.requestSerializer setValue:@"3" forHTTPHeaderField:@"uid"];
        
        [client.requestSerializer willChangeValueForKey:@"timeoutInterval"];
        client.requestSerializer.timeoutInterval = 15.0f;
        [client.requestSerializer didChangeValueForKey:@"timeoutInterval"];
        
        NSDictionary *info= [[NSBundle mainBundle] infoDictionary];
        
        NSString *type                = @"type/ios"; // 系统类型
        NSString *app_version_code    = [NSString stringWithFormat:@"app_version_code/%@",   info[@"CFBundleShortVersionString"]]; // app版本号
        NSString *app_version_name    = [NSString stringWithFormat:@"app_version_name/%@",   info[@"CFBundleVersion"]]; // app版本名
        NSString *phone_brand         = [NSString stringWithFormat:@"phone_brand/%@",         @"Apple"]; // 手机品牌
        NSString *phone_model         = [NSString stringWithFormat:@"phone_model/%@",         [YWXGetCurrentVC iphoneModel]]; // 手机型号
        NSString *system_version_code = [NSString stringWithFormat:@"system_version_code/%@",[[UIDevice currentDevice] systemVersion]]; // 系统版本号
        NSString *system_version_name = [NSString stringWithFormat:@"system_version_name/%@",[[UIDevice currentDevice] systemName]]; // 系统版本名
        
        NSString *UserAgent = [NSString stringWithFormat:@"%@;%@;%@;%@;%@;%@;%@",type,app_version_code,app_version_name,phone_brand,phone_model,system_version_code,system_version_name];
        [client.requestSerializer setValue:UserAgent forHTTPHeaderField:@"User-Agent"];
    });
    
    
    [LFNetworkTool lf_userCookie];
    return client;
}

@end


@interface LFNetworkTool ()
@end

@implementation LFNetworkTool


+ (LFNetworkTool *)shareInstance
{
    static LFNetworkTool *netTool = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        netTool = [[LFNetworkTool alloc]init];
        
        @weakify(self)
        [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationWillTerminateNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
            @strongify(self)
            [self clearCookies];
        }];
    });
    
    [self lf_userCookie];
    
    return netTool;
}

// cookie使用
//存储
+ (void) lf_cacheCookieFromTask:(NSURLSessionTask *) task
{
    // 获取到cookie的数组
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] getCookiesForTask:task completionHandler:^(NSArray<NSHTTPCookie *> * _Nullable cookies) {
        
        
        NSMutableDictionary *cookiesDic = [[LFCacheTool lf_getCacheObjectFromKey:COOKIES] mutableCopy];
        if (!cookiesDic) {
            cookiesDic = [NSMutableDictionary dictionary];
        }
        
        // 遍历数组
        for (NSHTTPCookie *cookie in cookies) {
            
            NSDictionary *cookieProperties = cookie.properties;
            
            [cookiesDic setObject:cookieProperties forKey:cookie.name];
        }
        [LFCacheTool lf_cacheObject:cookiesDic forKey:COOKIES];
    
//        NSLog(@"获取的cookie,%@",cookiesDic);
//        // 遍历数组
//        for (NSHTTPCookie *cookie in cookies) {
//
//            // 找到对应的cookie
//            if ([cookie.name isEqualToString:PHPSESSID]) {
//
//                // 拿到缓存里面的cookie字典
//                NSDictionary *cookieDic = [LFCacheTool lf_getCacheObjectFromKey:PHPSESSID];
//                // 拿到value
//                NSString *string = [cookieDic objectForKey:NSHTTPCookieValue];
//
//                // 判断当前任务的cookie和缓存里面的cookie是否是不同的
//                if (![string isEqualToString:cookie.value]) {
//
//                    // 如果不相同, 就缓存新的
//                    [LFCacheTool lf_cacheObject:cookie.properties forKey:PHPSESSID];
//                }
//            }
//        }
    }];
}

// 取出使用
+ (void) lf_userCookie
{
    NSMutableDictionary *cookieValue = [LFCacheTool lf_getCacheObjectFromKey:COOKIES];
    
    if (cookieValue) {
        NSMutableDictionary *dic = [NSMutableDictionary dictionary];
        [cookieValue enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            NSHTTPCookie *cookie = [[NSHTTPCookie alloc]initWithProperties:obj];
            
            // 没有结束时间的 有时间还没过期的,扔到cookie里面
            if (cookie.expiresDate == nil || [cookie.expiresDate compare:[NSDate date]] == NSOrderedDescending) {
                [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
                [dic setObject:obj forKey:cookie.name];
            }
        }];
//        NSLog(@"设置的新cookie:%@",dic);
//        NSHTTPCookie *cookie = [[NSHTTPCookie alloc]initWithProperties:cookieValue];
//
//        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
    }
    
//    NSLog(@"设置之后的cookie,%@",[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies);
}


/**
 清理所有cookie
 */
+ (void) lf_cleanCookies {
    NSMutableDictionary *cookieValue = [[LFCacheTool lf_getCacheObjectFromKey:COOKIES] mutableCopy];
    if (cookieValue) {
        [cookieValue enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            NSHTTPCookie *cookie = [[NSHTTPCookie alloc]initWithProperties:obj];
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
        }];
        [cookieValue removeAllObjects];
        [LFCacheTool lf_cacheObject:cookieValue forKey:COOKIES];
    }
//    NSLog(@"剩余的cookieValue: %@",cookieValue);
//    NSLog(@"NSHTTPCookieStorage: %@",[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies);
}


/**
 清理无用的cookie
 */
+ (void) clearCookies {
    
    NSMutableDictionary *cookieValue = [[LFCacheTool lf_getCacheObjectFromKey:COOKIES] mutableCopy];
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    if (cookieValue) {
        
        [cookieValue enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            NSHTTPCookie *cookie = [[NSHTTPCookie alloc]initWithProperties:obj];
            
            // 没有结束时间的 有时间但已过期的,删除
            if (cookie.expiresDate == nil || [cookie.expiresDate compare:[NSDate date]] == NSOrderedAscending) {
                [dic setObject:cookie.properties forKey:cookie.name];
            }
        }];
        [dic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            NSHTTPCookie *cookie = [[NSHTTPCookie alloc]initWithProperties:obj];
            [cookieValue removeObjectForKey:cookie.name];
        }];
        [LFCacheTool lf_cacheObject:cookieValue forKey:COOKIES];
    }
//    NSLog(@"删除多余无用cookie,%@",dic);
}

/**
 网络请求
 
 @param type 请求的类型
 @param urlS 主体URL
 @param parameters 参数
 @param success 成功结果回调
 @param failure 失败结果回调
 */

+ (void) httpRequest:(RequestType)type
                 url:(NSString *)urlS
                para:(NSDictionary *)parameters
             success:(HttpSuccessBlock)success
             failure:(HttpFailureBlock)failure;
{
    // 存储最后一次请求的时间
    NSDate *date = [NSDate date];
    [LFCacheTool lf_cacheObject:date forKey:REQUEST_LAST_TIME];
    
    UIApplication *app = [UIApplication sharedApplication];
    app.networkActivityIndicatorVisible = YES;
    [LFHTTPClient shareInstance].responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html",@"text/json", @"text/javascript",@"text/plain" ,nil];
    if (type == RequestTypeGET) {
        // GET 请求
        [[LFHTTPClient shareInstance] GET:urlS parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
            success(dic);
            app.networkActivityIndicatorVisible = NO;
            
            [self lf_cacheCookieFromTask:task];
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            failure(error);
            
            app.networkActivityIndicatorVisible = NO;
            
            [self lf_cacheCookieFromTask:task];
        }];
    } else {
        // POST 请求
        
        [[LFHTTPClient shareInstance] POST:urlS parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];

            success(dic);
            app.networkActivityIndicatorVisible = NO;
            
            [self lf_cacheCookieFromTask:task];
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            failure(error);
            
            app.networkActivityIndicatorVisible = NO;
            
            [self lf_cacheCookieFromTask:task];
            
        }];
    }
}


/**
 *  下载文件
 *
 *  @param path     url路径
 *  @param success  下载成功
 *  @param failure  下载失败
 *  @param progress 下载进度
 */

+ (void)downloadWithPath:(NSString *)path
                 success:(HttpSuccessBlock)success
                 failure:(HttpFailureBlock)failure
                progress:(HttpDownloadProgressBlock)progress {
    
    //获取完整的url路径
    NSString * urlString = [SEVER_HOST stringByAppendingPathComponent:path];
    
    //下载
    NSURL *URL = [NSURL URLWithString:urlString];
    
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    
    NSURLSessionDownloadTask *downloadTask = [[LFHTTPClient shareInstance] downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        
        progress(downloadProgress.fractionCompleted);
        
    } destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        
        //获取沙盒cache路径
        NSURL * documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        
        return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
        
        
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        
        if (error) {
            
            failure(error);
            
        } else {
            
            success(filePath.path);
            
        }
    }];
    
    [downloadTask resume];
    
}


/**
 *  上传图片
 *
 *  @param path     url地址
 *  @param images    UIImage对象数组
 *  @param imagekey    imagekey
 *  @param params  上传参数
 *  @param success  上传成功
 *  @param failure  上传失败
 *  @param progress 上传进度
 */

+ (void)uploadImageWithPath:(NSString *)path
                     params:(NSDictionary *)params
                  thumbName:(NSString *)imagekey
                     images:(NSArray *)images
                    success:(HttpSuccessBlock)success
                    failure:(HttpFailureBlock)failure
                   progress:(HttpUploadProgressBlock)progress {
    
    [[LFHTTPClient shareInstance] POST:path parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        
        //        for (UIImage *image in images) {
        //            NSData *data = UIImageJPEGRepresentation(image,0.5);
        //            [formData appendPartWithFileData:data
        //                                        name:[NSString stringWithFormat:@"%@_%lu",imagekey, (unsigned long)[images indexOfObject:image]]
        //                                    fileName:[NSString stringWithFormat:@"%@_%lu.jpg",imagekey,(unsigned long)[images indexOfObject:image]]
        //                                    mimeType:@"image/png"];
        //        }
        
        for (UIImage *image in images) {
            
            NSData *data = UIImageJPEGRepresentation(image,0.5);
            
            [formData appendPartWithFileData:data
                                        name:@"file"
                                    fileName:imagekey
                                    mimeType:@"image/jpg"];
        }
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        
        progress(uploadProgress.fractionCompleted);
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        success(responseObject);
        
        [self lf_cacheCookieFromTask:task];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        failure(error);
        
        [self lf_cacheCookieFromTask:task];
        
    }];
}


/**
 获取网络状态是否可用
 
 @param returnStatus 回调网络是否可用
 */
- (void) checkNetworkStatus:(void(^)(BOOL netUsable))returnStatus
{
    [self getNetorkStatus:^(AFNetworkReachabilityStatus status) {
        if (status == AFNetworkReachabilityStatusUnknown) {
            
            isNetworkUse = YES;
            
        } else if (status == AFNetworkReachabilityStatusReachableViaWiFi){
            
            isNetworkUse = YES;
            
        } else if (status == AFNetworkReachabilityStatusReachableViaWWAN){
            
            isNetworkUse = YES;
            
        } else if (status == AFNetworkReachabilityStatusNotReachable){
            
            // 网络异常操作
            isNetworkUse = NO;
            
        }
        
        // 更新网络相关状态属性
        self.netStatus = status;
        self.isNetUsable = isNetworkUse;
        
        [self.netStatusChangeSubject sendNext:@(status)];
        
        returnStatus(isNetworkUse);
    }];
}


/**
 获取实际的网络状态
 
 @param resultBack 回调实际的网络状态
 */
- (void) getNetorkStatus:(void(^)(AFNetworkReachabilityStatus status))resultBack
{
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        resultBack(status);
        [[NSNotificationCenter defaultCenter] postNotificationName:NetStatusChange object:nil];
    }];
}


/**
 结束网络监听
 */
- (void)stopChetNet
{
    [[AFNetworkReachabilityManager sharedManager] stopMonitoring];
}

- (RACSubject *)netStatusChangeSubject {
    if (!_netStatusChangeSubject) {
        _netStatusChangeSubject = [RACSubject subject];
    }
    return _netStatusChangeSubject;
}

@end
